/*
 * nwpu/2012/2012_1.c
 *
 * Harry Wei <harryxiyou@gmail.com> (C) 2013
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define SIZE		(100)

/*
 * Caculate with reverse polish notation.
 * 1, Scan stack.
 * 2, When a number, push into stack.
 * 3, When a operator, pull stack numbers.
 * 4, Caculate them and push the results.
 * 5, At last, we get the result.
 */

struct stack {
	unsigned long int number[SIZE];
	int pointer;
};

int main(int argc, char *argv[]) {
	char ch = 0;
	struct stack sk;
	char *scan = NULL;
	char *endptr = NULL;
	unsigned long int num = 0;
	unsigned long int calf = 0;
	unsigned long int cals = 0;
	unsigned long int result = 0;

	memset(&sk, 0, sizeof(struct stack));
	sk.pointer = 0;
	if (2 != argc) {
		fprintf(stderr, "%s\n", "Caculate sample:");
		fprintf(stderr, "%s\n", "./caculator 12+");
		return -1;
	}
//	printf("argv[1]: %s\n", argv[1]);
	scan = (char *) (&argv[1][0]);
	/*TODO: if not reverse polish notation, report error*/
	while ('\0' != *scan) {
//		printf("%c", *scan);
		/*TODO: check number first will get best performance*/
		if (*scan == '+') {
			sk.pointer -= 1;
			calf = sk.number[sk.pointer];
			sk.pointer -= 1;
			cals = sk.number[sk.pointer];
			result = calf + cals;
			sk.number[sk.pointer] = result;

		} else if (*scan == '-') {
			sk.pointer -= 1;
			calf = sk.number[sk.pointer];
			sk.pointer -= 1;
			cals = sk.number[sk.pointer];
			result = calf - cals;
			sk.number[sk.pointer] = result;
		} else if (*scan == '*') {
			sk.pointer -= 1;
			calf = sk.number[sk.pointer];
			sk.pointer -= 1;
			cals = sk.number[sk.pointer];
			result = calf * cals;
			sk.number[sk.pointer] = result;
		} else if (*scan == '/') {
			sk.pointer -= 1;
			calf = sk.number[sk.pointer];
			sk.pointer -= 1;
			cals = sk.number[sk.pointer];
			result = calf / cals;
			sk.number[sk.pointer] = result;
		} else {
			ch = *scan;
			calf = strtoul(&ch, &endptr, 0);
			printf("calf is %lu\n", calf);
			/*TODO: check fail candition, following are the same*/
			sk.number[sk.pointer] = calf;
			sk.pointer += 1;
		}
		scan += 1;
	}
	printf("result is: %lu", sk.number[sk.pointer]);
	return 0;
}